package com.yn.service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Function;
import com.yn.common.constants.Constants;
import com.yn.common.enums.*;
import com.yn.common.exception.TransitException;
import com.yn.common.model.coupon.StoreCoupon;
import com.yn.common.model.user.User;
import com.yn.common.model.user.UserBill;
import com.yn.common.model.zy.TCarFleetManageDO;
import com.yn.common.model.zy.TCarManageDO;
import com.yn.common.model.zyorder.ZyOrder;
import com.yn.common.model.zyorder.ZyOrderServiceT;
import com.yn.common.model.zyorder.ZyServiceConfig;
import com.yn.common.model.zyorder.ZyServiceRegionPrice;
import com.yn.common.page.BasePage;
import com.yn.common.request.driver.CarOrderFinishedRequest;
import com.yn.common.request.sc.PageParamRequest;
import com.yn.common.request.sc.StoreOrderRefundRequest;
import com.yn.common.request.zyorder.ZyOrderRequest;
import com.yn.common.request.zyorder.ZyOrderServiceRequest;
import com.yn.common.response.driver.ZyDriverCenterListResponse;
import com.yn.common.response.driver.ZyDriverContactResponse;
import com.yn.common.response.driver.ZyDriverOrderDetailResponse;
import com.yn.common.response.driver.ZyDriverOrderListResponse;
import com.yn.common.response.sc.BaseResult;
import com.yn.common.response.zyorder.ZyOrderQuoteResponse;
import com.yn.common.response.zyorder.ZyOrderServiceResponse;
import com.yn.common.utils.DateUtil;
import com.yn.common.utils.MoneyUtils;
import com.yn.common.utils.RedisUtil;
import com.yn.common.utils.TransitUtils;
import com.yn.service.dao.zy.ZyOrderDao;
import com.yn.service.service.*;
import com.yn.service.zy.TCarFleetManageService;
import com.yn.service.zy.TCarManageService;
import com.yn.service.zy.model.dto.ZyOrderDTO;
import com.yn.service.zy.model.query.ZyOrderQuery;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 转运订单 接口实现
 */
@Service
@Slf4j
public class ZyOrderServiceImpl extends ServiceImpl<ZyOrderDao, ZyOrder> implements ZyOrderService {

    @Autowired
    private ZyServiceConfigService zyServiceConfigService;

    @Autowired
    private ZyServiceRegionPriceService zyServiceRegionPriceService;

    @Autowired
    private ZyOrderServiceService zyOrderServiceService;

    @Autowired
    private StoreCouponService storeCouponService;

    @Autowired
    private ZyOrderDao zyOrderDao;

   /* @Autowired
    private ZyOrderService zyOrderService;*/

    @Autowired
    private StoreOrderService storeOrderService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private  UserService userService;

    @Autowired
    private TCarManageService tCarManageService;

    @Autowired
    private TCarFleetManageService tCarFleetManageService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private UserBillService userBillService;

    private Logger logger = LoggerFactory.getLogger(ZyOrderServiceImpl.class);

    @Override
    public ZyOrderQuoteResponse addOrder(ZyOrderRequest zyOrderRequest,Boolean isSaveDb) {
        Integer userId = userService.getUserId();
        // 生成订单号
        String zyOrderNo = TransitUtils.getOrderNo(EnumZyOrderNoStr.ZY_ORDER.getCode()+userId);
        ZyOrderQuoteResponse quote = new ZyOrderQuoteResponse();
        //距离
        Integer transferDistance = zyOrderRequest.getTransferDistance();
        //转换公里 四舍五入保留两个值
        Double transferDistanced = Math.round(transferDistance / 1000D * 100) / 100.0;
        quote.setTransferDistance(transferDistanced);
        transferDistance = (int)(transferDistanced * 1000);

        String startRegionCode = zyOrderRequest.getStartRegionCode();
        Integer transportType = zyOrderRequest.getTransportType();
        Integer couponId = zyOrderRequest.getCouponId();
        //1:普通订单 2:公益类型
        Integer orderType = zyOrderRequest.getOrderType();
        if (orderType == 2) {
            String welfareMaterial = zyOrderRequest.getWelfareMaterial();
            if (StringUtils.isEmpty(welfareMaterial)) {
                throw new TransitException("公益订单需要上传材料信息!");
            }
        }
        ZyOrder zyOrder = new ZyOrder();
        BeanUtils.copyProperties(zyOrderRequest, zyOrder);
        zyOrder.setOrderStatus(EnumZyOrderStatus.DFK.getCode());
        zyOrder.setTransferDistance(transferDistance);
        zyOrder.setOrderNo(zyOrderNo);
        zyOrder.setAppUserId(userId);
        Integer orderId=null;
        if (isSaveDb) {
            save(zyOrder);
            orderId = zyOrder.getId();
        }
        List<ZyOrderServiceRequest> zyServiceConfigRequests = zyOrderRequest.getZyServiceConfigRequests();
        if (CollectionUtils.isEmpty(zyServiceConfigRequests)) {
            throw new TransitException("患者信息不能为空!");
        }
        //服务费用
        List<ZyOrderServiceT> servicesMoney = new ArrayList<>();
        //服务总费用(分)
        Integer allServiceCost = 0;
        //转运费用
        Integer transferDistancePrice = 0;

       /* ZyOrderServiceRequest zyOrderServiceRequest = new ZyOrderServiceRequest();
        zyOrderServiceRequest.setServiceConfigId(transportType);
        zyServiceConfigRequests.add(zyOrderServiceRequest);*/

        List<ZyOrderServiceResponse> zyOrderServiceResponses = new ArrayList<>();
        for (ZyOrderServiceRequest zyServiceConfigRequest : zyServiceConfigRequests) {
            Integer serviceConfigId = zyServiceConfigRequest.getServiceConfigId();
            Integer unitValue = zyServiceConfigRequest.getUnitValue();
            if (serviceConfigId == null) {
                throw new TransitException("服务配置id不能为空!");
            }
            ZyServiceConfig byId = zyServiceConfigService.getById(serviceConfigId);
            if (byId == null) {
                throw new TransitException("服务配置不存在!");
            }
            //服务类型(1:转运/2:普通服务)
            Integer serviceType = byId.getServiceType();
            //服务类型（1:范围/2:单价）
            Integer serviceUnionType = byId.getServiceUnionType();
            //服务名称
            String serviceName = byId.getServiceName();
            String unit = byId.getUnit();
            LambdaQueryWrapper<ZyServiceRegionPrice> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ZyServiceRegionPrice::getServiceConfigId, serviceConfigId)
                    .eq(ZyServiceRegionPrice::getRegionCode, startRegionCode);
            ZyServiceRegionPrice zyServiceRegionPrice = zyServiceRegionPriceService.getOne(queryWrapper);
            if (zyServiceRegionPrice == null) {
                throw new TransitException("该区域未配置价格!");
            }
            Integer regionRangeDB = zyServiceRegionPrice.getRegionRange();
            Integer regionRange = Objects.isNull(regionRangeDB)?0:regionRangeDB*1000;

            Integer regionRangePrice = zyServiceRegionPrice.getRegionRangePrice();
            Integer unitPrice = zyServiceRegionPrice.getUnitPrice();
            Integer zyRangeMoney = 0;
            ZyOrderServiceT zyOrderServiceT = new ZyOrderServiceT();
            if (1 == serviceType) {//转运服务
                if ("km".toLowerCase().equals(unit.toLowerCase())) {
                    // 米/分
                    Double unitM = unitPrice / 1000D;
                    if (serviceUnionType == 1) { //范围价格
                        if(orderType == 2){
                            if (transferDistance<50*1000){
                                zyRangeMoney=0;
                            }else {
                                //超出区域范围值
                                Integer outRang = transferDistance - 50*1000;
                                Double outRangMoneyDouble = outRang * unitM;
                                zyRangeMoney = Math.toIntExact(Math.round(outRangMoneyDouble));
                                zyRangeMoney = zyRangeMoney + regionRangePrice;

                            }
                        }else {
                            if (transferDistance > regionRange) {
                                //超出区域范围值
                                Integer outRang = transferDistance - regionRange;
                                Double outRangMoneyDouble = outRang * unitM;
                                zyRangeMoney = Math.toIntExact(Math.round(outRangMoneyDouble));
                                zyRangeMoney = zyRangeMoney + regionRangePrice;
                            } else {
                                zyRangeMoney = regionRangePrice;
                            }
                        }
                    } else {
                        zyRangeMoney = Math.toIntExact(Math.round(unitM * transferDistance));
                    }
                }

                ZyOrderServiceResponse zyOrderServiceResponse = new ZyOrderServiceResponse();
                zyOrderServiceResponse.setServiceConfigName(serviceName);
                zyOrderServiceResponse.setUnitPrice(MoneyUtils.fen2yuan(unitPrice));
                zyOrderServiceResponse.setRegionRange(regionRangeDB);
                zyOrderServiceResponse.setRegionRangePrice(MoneyUtils.fen2yuan(regionRangePrice));
                zyOrderServiceResponse.setServiceUnionType(serviceUnionType);
                zyOrderServiceResponse.setUnit(unit);
                quote.setZyOrderServiceResponse(zyOrderServiceResponse);


                zyOrderServiceT.setServiceCost(zyRangeMoney);
                zyOrderServiceT.setServiceConfigId(serviceConfigId);
                zyOrderServiceT.setUnitPrice(unitPrice);
                zyOrderServiceT.setUnitValue(transferDistance);
                zyOrderServiceT.setUnit(unit);
                zyOrderServiceT.setZyOrderId(orderId);
                zyOrderServiceT.setRegionRange(regionRangeDB);
                zyOrderServiceT.setRegionRangePrice(regionRangePrice);
                 zyOrderServiceT.setServiceType(serviceType);
                transferDistancePrice = zyRangeMoney;
                servicesMoney.add(zyOrderServiceT);
            } else {//普通服务
                ZyOrderServiceResponse zyOrderServiceResponse = new ZyOrderServiceResponse();
                zyOrderServiceResponse.setServiceConfigName(serviceName);
                zyOrderServiceResponse.setUnitPrice(MoneyUtils.fen2yuan(unitPrice));
                zyOrderServiceResponse.setRegionRange(regionRangeDB);
                if (serviceUnionType == 1) {
                    zyOrderServiceResponse.setRegionRangePrice(MoneyUtils.fen2yuan(regionRangePrice));
                }
                zyOrderServiceResponse.setServiceUnionType(serviceUnionType);
                zyOrderServiceResponse.setUnit(unit);
                quote.setZyOrderServiceResponse(zyOrderServiceResponse);
                if ("km".toLowerCase().equals(unit.toLowerCase())) {
                    // 米/分
                    Double unitM = unitPrice / 1000D;
                    if (serviceUnionType == 1) { //范围价格
                        if (transferDistance > regionRange) {
                            //超出区域范围值
                            Integer outRang = transferDistance - regionRange;
                            Double outRangMoneyDouble = outRang * unitM;
                            zyRangeMoney = Math.toIntExact(Math.round(outRangMoneyDouble));
                            zyRangeMoney = zyRangeMoney + regionRangePrice;
                            zyOrderServiceResponse.setRegionRange(regionRangeDB);
                            zyOrderServiceResponse.setServiceCost(MoneyUtils.fen2yuan(zyRangeMoney));
                        } else {
                            zyRangeMoney = regionRangePrice;
                        }
                    } else {
                        zyRangeMoney = Math.toIntExact(Math.round(unitM * transferDistance));
                    }

                } else {
                    zyRangeMoney = unitPrice * unitValue;
                    zyOrderServiceResponse.setServiceCost(MoneyUtils.fen2yuan(zyRangeMoney));
                }
                zyOrderServiceResponses.add(zyOrderServiceResponse);

                zyOrderServiceT.setServiceCost(zyRangeMoney);
                zyOrderServiceT.setServiceConfigId(serviceConfigId);
                zyOrderServiceT.setUnitPrice(unitPrice);
                zyOrderServiceT.setUnitValue(transferDistance);
                zyOrderServiceT.setUnit(unit);
                zyOrderServiceT.setZyOrderId(orderId);
                zyOrderServiceT.setRegionRange(regionRangeDB);
                zyOrderServiceT.setRegionRangePrice(regionRangePrice);
                allServiceCost += zyRangeMoney;
                servicesMoney.add(zyOrderServiceT);

            }
        }
        if (allServiceCost>0){
            quote.setAllServiceCost(MoneyUtils.fen2yuan(allServiceCost));
        }

        if (CollectionUtils.isNotEmpty(zyOrderServiceResponses)) {
            quote.setZyOrderServiceResponses(zyOrderServiceResponses);
        }
        if (isSaveDb) {
            zyOrderServiceService.saveBatch(servicesMoney);
        }



        Integer orderAllPrice = allServiceCost + transferDistancePrice;
        //单子的预估金额的总金额(元)
        quote.setOrderAllPrice(MoneyUtils.fen2yuan(orderAllPrice));
        ZyOrder byId =null;
        if (isSaveDb) {
            byId = getById(orderId);
            byId.setAllServiceCost(allServiceCost);
            byId.setTransportType(transportType);
            byId.setTransferDistancePrice(transferDistancePrice);
            byId.setOrderAllPrice(orderAllPrice);
        }

        //计算优惠卷
        Integer couponPrice = 0;
        Integer orderPayPrice = orderAllPrice;
        if (couponId != null) {
            StoreCoupon byId1 = storeCouponService.getById(couponId);
            if (byId1 == null) {
                throw new TransitException("所使用优惠券不存在!");
            }
            checkCoupon(byId1);
            BigDecimal money = byId1.getMoney();
            couponPrice = money.intValue();
            if (couponPrice > 0) {
                orderPayPrice = orderPayPrice - couponPrice;
                if (isSaveDb) {
                    byId.setCouponPrice(couponPrice);
                }

            }
        }
      /*  // 缓存订单
        String key = userId + DateUtil.getNowTime().toString()+ TransitUtils.getUuid();
        redisUtil.set(PreOrderCashEnum.PRE_ZY_ORDER + key, JSONObject.toJSONString(quote), Constants.ORDER_CASH_CONFIRM, TimeUnit.MINUTES);*/
       if (isSaveDb){
           byId.setOrderPayPrice(orderPayPrice);
           updateById(byId);
           quote.setZyOrderNo(zyOrderNo);
       }

        return quote;
    }

    @Override
    public ZyOrderQuoteResponse getQuote(ZyOrderRequest zyOrderRequest) {
        ZyOrderQuoteResponse zyOrderQuoteResponse = addOrder(zyOrderRequest, false);
        return zyOrderQuoteResponse;
    }

    @Override
    public ZyOrderQuoteResponse getZyOrderDetail(String orderNo) {

        LambdaQueryWrapper<ZyOrder> zyOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        zyOrderLambdaQueryWrapper.eq(ZyOrder::getOrderNo, orderNo);
        ZyOrder one = getOne(zyOrderLambdaQueryWrapper);
        if (one == null) {
            throw new TransitException("订单不存在!");
        }
        ZyOrderQuoteResponse zyOrderQuoteResponse = new ZyOrderQuoteResponse();
        //转运距离
        Integer transferDistance = one.getTransferDistance();
        Double transferDistanceD = Math.round(transferDistance / 1000D * 100) / 100.0;
        zyOrderQuoteResponse.setTransferDistance(transferDistanceD);
        //服务总费用
        Integer allServiceCost = one.getAllServiceCost();
        if (allServiceCost!=null &&allServiceCost>0){
            zyOrderQuoteResponse.setAllServiceCost(MoneyUtils.fen2yuan(allServiceCost));
        }

        //应支付金额
        Integer orderAllPrice = one.getOrderAllPrice();
        if (orderAllPrice!=null &&orderAllPrice>0){
            zyOrderQuoteResponse.setOrderAllPrice(MoneyUtils.fen2yuan(orderAllPrice));
        }
        //优惠金额
        Integer couponPrice = one.getCouponPrice();
        if (couponPrice!=null &&couponPrice>0){
            zyOrderQuoteResponse.setCouponPrice(MoneyUtils.fen2yuan(couponPrice));
        }
        //实际已支付金额
        Integer orderPayPrice = one.getOrderPayPrice();
        if (orderPayPrice!=null &&orderPayPrice>0){
            zyOrderQuoteResponse.setOrderPayPrice(MoneyUtils.fen2yuan(orderPayPrice));
        }

        //转运费用
        LambdaQueryWrapper<ZyOrderServiceT> zyOrderServiceTLambdaQueryWrapper = new LambdaQueryWrapper<>();
        zyOrderServiceTLambdaQueryWrapper.eq(ZyOrderServiceT::getZyOrderId, one.getId());
        List<ZyOrderServiceT> list = zyOrderServiceService.list(zyOrderServiceTLambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            ZyOrderServiceT zyOrderServiceT =
                    list.parallelStream().filter(p -> "1".equals(p.getServiceType())).findFirst().orElse(null);
            if (zyOrderServiceT != null) {
                Integer serviceConfigId = zyOrderServiceT.getServiceConfigId();
                ZyOrderServiceResponse zyOrderServiceResponse = new ZyOrderServiceResponse();
                ZyServiceConfig byId = zyServiceConfigService.getById(serviceConfigId);
                String serviceName = byId.getServiceName();
                zyOrderServiceResponse.setServiceConfigName(serviceName);

                zyOrderServiceResponse.setUnitPrice(MoneyUtils.fen2yuan(zyOrderServiceT.getUnitPrice()));
                zyOrderServiceResponse.setRegionRange(zyOrderServiceT.getRegionRange() / 1000);
                zyOrderServiceResponse.setRegionRangePrice(MoneyUtils.fen2yuan(zyOrderServiceT.getServiceRegionPriceId()));
                zyOrderServiceResponse.setServiceUnionType(byId.getServiceUnionType());
                zyOrderServiceResponse.setUnit(byId.getUnit());
                Integer serviceCost = zyOrderServiceT.getServiceCost();
                if (serviceCost!=null &&serviceCost>0){
                    zyOrderServiceResponse.setServiceCost(MoneyUtils.fen2yuan(serviceCost));
                }
                zyOrderQuoteResponse.setZyOrderServiceResponse(zyOrderServiceResponse);
            }
            //服务费用
            List<ZyOrderServiceT> collect =
                    list.parallelStream().filter(p -> "1".equals(p.getServiceType())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                List<ZyOrderServiceResponse> zyOrderServiceResponses = new ArrayList<>();
                collect.forEach(p -> {
                    ZyOrderServiceResponse zyOrderServiceResponse = new ZyOrderServiceResponse();
                    ZyServiceConfig byId = zyServiceConfigService.getById(p.getServiceConfigId());
                    zyOrderServiceResponse.setServiceConfigName(byId.getServiceName());
                    zyOrderServiceResponse.setUnitPrice(MoneyUtils.fen2yuan(p.getUnitPrice()));
                    zyOrderServiceResponse.setUnitPrice(MoneyUtils.fen2yuan(p.getUnitPrice()));
                    zyOrderServiceResponse.setRegionRange(p.getRegionRange() / 1000);
                    zyOrderServiceResponse.setRegionRangePrice(MoneyUtils.fen2yuan(p.getServiceRegionPriceId()));
                    zyOrderServiceResponse.setServiceUnionType(byId.getServiceUnionType());
                    zyOrderServiceResponse.setUnit(byId.getUnit());
                    if(p.getUnit().contains("层")){
                        zyOrderServiceResponse.setUnitValue(p.getUnitValue());
                    }
                    Integer serviceCost = p.getServiceCost();
                    if (serviceCost!=null &&serviceCost>0){
                        zyOrderServiceResponse.setServiceCost(MoneyUtils.fen2yuan(serviceCost));
                    }
                    zyOrderServiceResponses.add(zyOrderServiceResponse);
                });
                zyOrderQuoteResponse.setZyOrderServiceResponses(zyOrderServiceResponses);
            }
        }
        return zyOrderQuoteResponse;
    }

    @Override
    @Transactional
    public void cancelOrder(String orderNo) {
        LambdaQueryWrapper<ZyOrder> zyOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        zyOrderLambdaQueryWrapper.eq(ZyOrder::getOrderNo, orderNo);
        ZyOrder one = getOne(zyOrderLambdaQueryWrapper);
        if (one== null) {
            throw new TransitException("订单不存在！");
        }
        one.setOrderStatus(EnumZyOrderStatus.YQX.getCode());
        Boolean payStatus = one.getPayStatus();
        if (payStatus) {
            StoreOrderRefundRequest request =new StoreOrderRefundRequest();
            request.setOrderNo(orderNo);
            Integer orderPayPrice = one.getOrderPayPrice();
            BigDecimal amount=new BigDecimal(0);
            if (orderPayPrice!=null &&orderPayPrice>0){
                Double orderPayPriceD = Math.round(orderPayPrice / 100D * 100) / 100.0;
                amount= BigDecimal.valueOf(orderPayPriceD);
                request.setAmount(amount);
                Boolean blg=storeOrderService.refund(request);
                one.setOrderReturnStatus(EnumReturnStatus.RETURN_SUCCESS.getCode());
                one.setOrderReturnMoney(orderPayPrice);
                if (!blg){
                    logger.error("订单取消失败原因:{}","退款失败");
                    one.setOrderReturnStatus(EnumReturnStatus.RETURN_FAIL.getCode());
                    one.setOrderReturnMoney(0);
                }
            }
        }
        updateById(one);

    }

    @Override
    public  void  del(String orderNos,Integer userId) {
        LambdaQueryWrapper<ZyOrder> zyOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        zyOrderLambdaQueryWrapper.eq(ZyOrder::getAppUserId, userId);
        zyOrderLambdaQueryWrapper.in(ZyOrder::getOrderNo, orderNos);
        List<ZyOrder> list = list(zyOrderLambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            list.parallelStream().forEach(p-> p.setIsDelTag(true));
            this.updateBatchById(list);
        }

    }

    @Override
    public BasePage<ZyDriverOrderListResponse> getZyOrderList(Integer transportType, PageParamRequest pageRequest) {
         PageHelper.startPage(pageRequest.getPage(), pageRequest.getLimit());
        //只有司机可以查看
        /*User userInfo = userService.getInfoException();
        if(!Objects.equals(userInfo.getIdentity(), UserIdentityEnum.FLEET_ENTRY_PERSONNEL.getCode())) {
            throw new TransitException("您没有权限查看订单列表");
        }*/
        //构建查询条件 接单状态为待接单 用车时间大于当前时间 且支付状态为已支付 没有逻辑删除的订单
        LambdaQueryWrapper<ZyOrder> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(ZyOrder::getOrderStatus, EnumZyOrderStatus.DJD.getCode());
        lambdaQuery.gt(ZyOrder::getUseCarDateTime, DateUtil.nowDateTime());
        lambdaQuery.eq(ZyOrder::getPayStatus, true);
        lambdaQuery.eq(ZyOrder::getIsDelTag, false);
        lambdaQuery.orderByDesc(ZyOrder::getCreateTime);
        List<ZyOrder> zyOrderList = list(lambdaQuery);
        if (CollectionUtils.isEmpty(zyOrderList)) {
            return  BasePage.restPage(new ArrayList<>());
        }
        BasePage<ZyOrder> pageList = BasePage.restPage(zyOrderList);
        List<ZyDriverOrderListResponse> zyDriverOrderListResponses = new ArrayList<>(zyOrderList.size());
        for (ZyOrder zyOrder : zyOrderList) {
            ZyDriverOrderListResponse response = new ZyDriverOrderListResponse();
            response.setOrderNo(zyOrder.getOrderNo());
            response.setId(zyOrder.getId());
            response.setStartRegionCode(zyOrder.getStartRegionCode());
            response.setEndRegionCode(zyOrder.getEndRegionCode());
            response.setStartDestination(zyOrder.getStartDestination());
            response.setEndDestination(zyOrder.getEndDestination());
            response.setStartLocality(zyOrder.getStartLocality());
            response.setEndLocality(zyOrder.getEndLocality());
            response.setRidingNumber(zyOrder.getRidingNumber());
            //订单类型
            response.setOrderType(zyOrder.getOrderType());
            response.setOrderTypeStr(ZyOrderTypeEnum.getByCode(zyOrder.getOrderType()).getName());
            //转运类型
            response.setTransportType(zyOrder.getTransportType());
            response.setTransportTypeStr(ZyTransportTypeEnum.getByCode(zyOrder.getTransportType()).getName());
            //将useCarDateTime转为LocalDateTime并格式化为年月日时分秒
            // 转换Date为LocalDateTime
             /*Date useCarDateTime = zyOrder.getUseCarDateTime();
             LocalDateTime localDateTime = useCarDateTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
             DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
             response.setUserCarDateTime(localDateTime.format(formatter));*/
            response.setUserCarDateTime(DateUtil.dateToStr(zyOrder.getUseCarDateTime(), Constants.DATE_FORMAT));
            //将距离转化为KM
            Integer transferDistance = zyOrder.getTransferDistance();
            Double transferDistance2Db =(transferDistance *100.0/1000)/100;
            response.setTransferDistance(transferDistance2Db);
            //response.setOrderPayPrice(zyOrder.getOrderPayPrice());
            response.setOrderAllPrice(zyOrder.getOrderAllPrice());
            zyDriverOrderListResponses.add(response);
        }
        BasePage<ZyDriverOrderListResponse> basePage = BasePage.restPage(zyDriverOrderListResponses);
        BeanUtils.copyProperties(pageList, basePage,"list");
        return basePage;
    }

    @Override
    public BasePage<ZyDriverCenterListResponse> zyOrderCenterList(Integer isAsc, PageParamRequest pageRequest) {
        PageHelper.startPage(pageRequest.getPage(), pageRequest.getLimit());
        Integer userId = userService.getUserId();
        if(userId == null || userId == 0){
            throw new TransitException("请先登录");
        }
        //构建查询条件 接单id为当前用户 接单状态大于等于已接单  且支付状态为已支付 没有逻辑删除的订单
        LambdaQueryWrapper<ZyOrder> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(ZyOrder::getCarAppUserId,userId);
        lambdaQuery.ge(ZyOrder::getOrderStatus, EnumZyOrderStatus.YJD.getCode());
        lambdaQuery.eq(ZyOrder::getPayStatus, true);
        lambdaQuery.eq(ZyOrder::getIsDelTag, false);
        if(isAsc!=null && isAsc==1){
            lambdaQuery.orderByAsc(ZyOrder::getCreateTime);
        }else{
            lambdaQuery.orderByDesc(ZyOrder::getCreateTime);
        }
        List<ZyOrder> zyOrderList = list(lambdaQuery);
        if (CollectionUtils.isEmpty(zyOrderList)) {
            return  BasePage.restPage(new ArrayList<>());
        }
        BasePage<ZyOrder> pageList = BasePage.restPage(zyOrderList);
        List<ZyDriverCenterListResponse> zyDriverOrderListResponses = new ArrayList<>(zyOrderList.size());
        for (ZyOrder zyOrder : zyOrderList) {
            ZyDriverCenterListResponse transfer = ZyDriverCenterListResponse.transfer(zyOrder);
            zyDriverOrderListResponses.add(transfer);
        }

        BasePage<ZyDriverCenterListResponse> basePage = BasePage.restPage(zyDriverOrderListResponses);
        BeanUtils.copyProperties(pageList, basePage, "list");

        return basePage;
    }

    @Override
    public BasePage<ZyOrderDTO> listPage1(ZyOrderQuery query, PageParamRequest pageRequest) {
        PageHelper.startPage(pageRequest.getPage(), pageRequest.getLimit());
        LambdaQueryWrapper<ZyOrder> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(query.getOrderNo())) {
            queryWrapper.eq(ZyOrder::getOrderNo, query.getOrderNo());
        }
        List<ZyOrder> zyOrders = baseMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(zyOrders)) {
            return BasePage.restPage(new ArrayList<>());
        }
        BasePage<ZyOrder> pageList = BasePage.restPage(zyOrders);
        ArrayList<ZyOrderDTO> zyOrderDTOList = new ArrayList<>(zyOrders.size());
        for (ZyOrder zyOrder : zyOrders) {
            ZyOrderDTO dto = ZyOrderDTO.transform(zyOrder);
            zyOrderDTOList.add(dto);
        }
        BasePage<ZyOrderDTO> basePage = BasePage.restPage(zyOrderDTOList);
        BeanUtils.copyProperties(pageList, basePage,"list");
        return basePage;
    }



    @Override
    @Transactional
    public void takeOrder(String orderNo) {
        //获取用户信息，只有用户身份是司机入住人员的才能看单子详情
        User user = userService.getInfoException();
        List<TCarFleetManageDO> infoByAppUserId = tCarFleetManageService.getInfoByAppUserId(user.getUid());
        if(Collections.isEmpty(infoByAppUserId)){
            throw new TransitException("您不是司机或者还未通过审核");
        }
        //只有在运的车队才能接单
        boolean inService=false;
        for (TCarFleetManageDO fleetManageDO : infoByAppUserId) {
            if(fleetManageDO.getPostStatus().equals(PostStatusEnum.IN_SERVICE.getCode())){
                inService=true;
                break;
            }
        }
        if(!inService){
            throw new TransitException("您不是在运状态");
        }
        //只有在岗的司机才能接单
        /*if(!Objects.equals(tCarManageDO.getCarStatus(), CarStatusEnum.FREE.getCode())){
            throw new TransitException("目前司机不在岗");
        }*/
        //加分布式锁
        RLock lock = redissonClient.getLock("takeOrder:" + orderNo);
        boolean isLock = lock.tryLock();
        if(!isLock){
            throw new RuntimeException("抢单人太多，请稍后重试");
        }
        ZyOrder order = lambdaQuery().eq(ZyOrder::getOrderNo, orderNo).one();
        if(order == null||order.getOrderStatus() != 1){
            throw new TransitException("订单已被抢完");
        }
        try {
            //车辆信息 车信息
            /*Integer driverMangeId = tCarManageDO.getId();
            order.setCarManageId(driverMangeId);*/
            //车长id
            order.setCarAppUserId(user.getUid());
            //订单状态设置为已接单
            order.setOrderStatus(EnumZyOrderStatus.YJD.getCode());
            order.setUpdateById(user.getUid());
            //乐观锁进行判断
            boolean update = lambdaUpdate().eq(ZyOrder::getId, order.getId()).eq(ZyOrder::getOrderStatus, 1).update(order);
            if(!update){
                throw new TransitException("订单已被抢完");
            }

            //异步发送短信给用户 TODO
        } finally {
            lock.unlock();
        }
    }

    @Override
    @Transactional
    public void driverCancelOrder(String orderNo) {
        //获取当前用户id
        Integer userId = userService.getUserIdException();
        ZyOrder order = lambdaQuery()
                .eq(ZyOrder::getOrderNo, orderNo)
                .eq(ZyOrder::getCarAppUserId, userId)
                .eq(ZyOrder::getOrderStatus,EnumZyOrderStatus.YJD.getCode()).one();
        if(order == null){
            throw new TransitException("订单存在问题");
        }
        order.setOrderStatus(EnumZyOrderStatus.DJD.getCode());
        order.setCarAppUserId(-1);
        order.setUpdateById(userId);
        lambdaUpdate().eq(ZyOrder::getId, order.getId()).update(order);
    }

    @Override
    public ZyDriverOrderDetailResponse getZyDriverOrderDetail(String orderNo) {
        ZyOrder zyOrder = lambdaQuery().eq(ZyOrder::getOrderNo, orderNo).one();
        if(zyOrder == null){
            throw new TransitException("订单不存在");
        }
        //只有管理员和司机可以查看
        /*User userInfo = userService.getInfoException();
        if(!Objects.equals(userInfo.getIdentity(), UserIdentityEnum.BACKGROUND_MANAGER.getCode())
                && !Objects.equals(userInfo.getIdentity(), UserIdentityEnum.FLEET_ENTRY_PERSONNEL.getCode())) {
            throw new TransitException("您没有权限查看订单列表");
        }*/
        //TCarManageDO carManageDO = tCarManageService.getById(zyOrder.getCarManageId());
        User user = userService.getInfoException();
        /*if(user.getPhone()==null || !user.getPhone().equals(carManageDO.getCarLinkNumber())){
            throw new TransitException("您没有权限查看此订单");
        }*/
        List<TCarFleetManageDO> infoByAppUserId = tCarFleetManageService.getInfoByAppUserId(user.getUid());
        if(Collections.isEmpty(infoByAppUserId)){
            throw new TransitException("您不是司机或者还未通过审核");
        }
        ZyDriverOrderDetailResponse response = new ZyDriverOrderDetailResponse();
        response.setOrderNo(zyOrder.getOrderNo());
        response.setId(zyOrder.getId());
        response.setStartRegionCode(zyOrder.getStartRegionCode());
        response.setEndRegionCode(zyOrder.getEndRegionCode());
        response.setStartDestination(zyOrder.getStartDestination());
        response.setEndDestination(zyOrder.getEndDestination());
        response.setStartLocality(zyOrder.getStartLocality());
        response.setEndLocality(zyOrder.getEndLocality());
        response.setRidingNumber(zyOrder.getRidingNumber());
        response.setOrderType(zyOrder.getOrderType());
        response.setOrderTypeStr(ZyOrderTypeEnum.getByCode(zyOrder.getOrderType()).getName());
        response.setTransportType(zyOrder.getTransportType());
        response.setTransportTypeStr(ZyTransportTypeEnum.getByCode(zyOrder.getTransportType()).getName());
        response.setRemark(zyOrder.getRemark());
        ZyOrderQuoteResponse zyOrderDetail = getZyOrderDetail(orderNo);
        BeanUtil.copyProperties(zyOrderDetail,response);
        return response;
    }

    /**
     * 司机端查询转运订单详情
    * */
    @Override
    public ZyDriverContactResponse getOrderDetail(String orderNo) {
        //管理端查看订单详情
        //获取当前用户信息
       /* User user = userService.getInfoException();
        if(!Objects.equals(user.getIdentity(), UserIdentityEnum.BACKGROUND_MANAGER.getCode())){
            throw new TransitException("您没有权限查看");
        }*/
        ZyOrder zyOrder = lambdaQuery().eq(ZyOrder::getOrderNo, orderNo).one();
        if(zyOrder == null){
            throw new TransitException( "订单不存在");
        }
        ZyDriverContactResponse response = new ZyDriverContactResponse();
        response.setUserOrderName(zyOrder.getUserOrderName());
        response.setUserOrderPhone(zyOrder.getUserOrderPhone());

        response.setOrderNo(zyOrder.getOrderNo());
        response.setId(zyOrder.getId());
        response.setStartRegionCode(zyOrder.getStartRegionCode());
        response.setEndRegionCode(zyOrder.getEndRegionCode());
        response.setStartDestination(zyOrder.getStartDestination());
        response.setEndDestination(zyOrder.getEndDestination());
        response.setStartLocality(zyOrder.getStartLocality());
        response.setEndLocality(zyOrder.getEndLocality());
        response.setRidingNumber(zyOrder.getRidingNumber());
        //订单类型
        response.setOrderType(zyOrder.getOrderType());
        response.setOrderTypeStr(ZyOrderTypeEnum.getByCode(zyOrder.getOrderType()).getName());
        //转运类型
        response.setTransportType(zyOrder.getTransportType());
        response.setTransportTypeStr(ZyTransportTypeEnum.getByCode(zyOrder.getTransportType()).getName());
        //订单状态
        response.setOrderStatus(zyOrder.getOrderStatus());
        response.setOrderStatusStr(EnumZyOrderStatus.getByCode(zyOrder.getOrderStatus()).getName());
        response.setRemark(zyOrder.getRemark());
        ZyOrderQuoteResponse zyOrderDetail = getZyOrderDetail(orderNo);
        BeanUtil.copyProperties(zyOrderDetail,response);

        return response;
    }

    @Override
    public ZyDriverContactResponse getOrderCenterDetail(String orderNo) {
        //获取当前用户信息
        User user = userService.getInfoException();
        ZyOrder zyOrder = lambdaQuery().eq(ZyOrder::getOrderNo, orderNo)
                .ge(ZyOrder::getOrderStatus, EnumZyOrderStatus.YJD.getCode())
                .eq(ZyOrder::getCarAppUserId, user.getUid())
                .eq(ZyOrder::getIsDelTag, false)
                .one();
        if(zyOrder == null){
            throw new TransitException( "订单不存在");
        }
        ZyDriverContactResponse response = new ZyDriverContactResponse();
        //如果订单状态为已取消，司机无法看见乘客手机号和姓名
        if(!zyOrder.getOrderStatus().equals(EnumZyOrderStatus.YQX.getCode())){
            response.setUserOrderName(zyOrder.getUserOrderName());
            response.setUserOrderPhone(zyOrder.getUserOrderPhone());
        }
        response.setOrderNo(zyOrder.getOrderNo());
        response.setId(zyOrder.getId());
        response.setStartRegionCode(zyOrder.getStartRegionCode());
        response.setEndRegionCode(zyOrder.getEndRegionCode());
        response.setStartDestination(zyOrder.getStartDestination());
        response.setEndDestination(zyOrder.getEndDestination());
        response.setStartLocality(zyOrder.getStartLocality());
        response.setEndLocality(zyOrder.getEndLocality());
        response.setRidingNumber(zyOrder.getRidingNumber());
        response.setOrderType(zyOrder.getOrderType());
        response.setOrderTypeStr(ZyOrderTypeEnum.getByCode(zyOrder.getOrderType()).getName());
        response.setTransportType(zyOrder.getTransportType());
        response.setTransportTypeStr(ZyTransportTypeEnum.getByCode(zyOrder.getTransportType()).getName());
        response.setOrderStatus(zyOrder.getOrderStatus());
        response.setOrderStatusStr(EnumZyOrderStatus.getByCode(zyOrder.getOrderStatus()).getName());
        response.setRemark(zyOrder.getRemark());

        //如果是接单，这里展示为接单时间，如果为取消，这里展示为取消时间，如果已完成，这里展示为完成时间
        response.setUpdateTime(DateUtil.dateToStr(zyOrder.getUpdateTime(), Constants.DATE_FORMAT));

        ZyOrderQuoteResponse zyOrderDetail = getZyOrderDetail(orderNo);
        BeanUtil.copyProperties(zyOrderDetail,response);

        return response;
    }

    @Override
    @Transactional
    public void OrderFinished(String orderNo,Integer orderStatus) {
       /* if(!Objects.equals(orderStatus, EnumZyOrderStatus.YSD.getCode())){
            log.info("订单状态不是已送达，不能完成订单");
            throw new TransitException("订单状态异常");
        }*/
        // 根据订单号，订单状态为以上车查询表数据
        ZyOrder order = lambdaQuery().eq(ZyOrder::getOrderNo, orderNo).one();
        if (null == order) {
            throw new TransitException("订单不存在");
        }
        if(Objects.equals(orderStatus, EnumZyOrderStatus.YSD.getCode())){
            if (!Objects.equals(order.getOrderStatus(), EnumZyOrderStatus.YSC.getCode())) {
                throw new TransitException("订单状态异常");
            }
            order.setOrderStatus(EnumZyOrderStatus.DPJ.getCode());
        }else if(Objects.equals(orderStatus, EnumZyOrderStatus.YSC.getCode())){
            if (!Objects.equals(order.getOrderStatus(), EnumZyOrderStatus.YJD.getCode())) {
                throw new TransitException("订单状态异常");
            }
            order.setOrderStatus(EnumZyOrderStatus.YSC.getCode());
        }
        // 获取当前用户信息，判断是用户还是司机
        User user = userService.getInfoException();
        //TCarManageDO one = tCarManageService.lambdaQuery().eq(TCarManageDO::getAppUserId, userId).one();
        /*if (one != null) {
            // 司机端确认订单 需要进行校验，用户端不需要进行位置校验
            if (!(request.getEndRegionCode().equals(order.getEndRegionCode()) || request.getEndDestination().equals(order.getEndDestination()) || request.getEndLocality().equals(order.getEndLocality()))) {
                throw new TransitException("目的地信息异常");
            }
        }*/
        // 将订单状态设置为待评价
        order.setUpdateTime(new Date());
        order.setUpdateById(user.getUid());
        order.setFinishById(user.getUid());
        boolean isFinished = updateById(order);
        if (!isFinished) {
            throw new TransitException("订单完成失败");
        }
        // 异步收款
        //addMoney2Driver(order);
    }



    @Async
    @Transactional
    public void addMoney2Driver(ZyOrder order) {
        //获取司机的信息
        Integer carManageId = order.getCarManageId();
        TCarManageDO carManage = tCarManageService.getById(carManageId);
        User user = userService.getInfoByUid(carManage.getAppUserId());
        if(user == null){
            throw new TransitException("司机不存在");
        }
        //将订单的余额添加到司机用户表中  TODO 金额问题(目前司机收的是订单的实际付款金额)
        Integer orderAllPrice = order.getOrderAllPrice();
        user.setNowMoney(user.getIncome().add(new BigDecimal(orderAllPrice)));
        //用户账单表
        UserBill userBill = new UserBill();
        userBill.setUid(carManage.getAppUserId());
        userBill.setLinkId(order.getOrderNo());
        userBill.setPm(1);//获得
        userBill.setTitle("完成订单");
        userBill.setCategory(Constants.USER_BILL_INCOME_MONEY);
        userBill.setType(Constants.USER_BILL_TYPE_TRANSFER_IN);
        userBill.setNumber(new BigDecimal(orderAllPrice));
        userBill.setBalance(user.getIncome().add(new BigDecimal(orderAllPrice)));
        userBill.setMark(StrUtil.format("订单完成获得{}元", orderAllPrice));
        userBill.setStatus(UserBillStatusEnum.VALID.getCode());
        userBill.setCreateTime(DateUtil.nowDateTime());
        userBillService.save(userBill);
    }



    //检查优惠卷是否可用
    public static void checkCoupon(StoreCoupon storeCoupon) {
        if (storeCoupon == null || storeCoupon.getIsDel() || !storeCoupon.getStatus()) {
            throw new TransitException("所使用优惠券不存在或已失效！");
        }
        Date useStartTime = storeCoupon.getUseStartTime();
        Date useEndTime = storeCoupon.getUseEndTime();
        //看是否过期
        if (!(useStartTime == null)) {
            //非永久可领取
            String date = DateUtil.nowDateTimeStr();
            int result = DateUtil.compareDate(date, DateUtil.dateToStr(storeCoupon.getReceiveEndTime(), Constants.DATE_FORMAT), Constants.DATE_FORMAT);
            if (!(result == 1)) {
                //过期了
                throw new TransitException("所使用优惠券不在使用期限内！");
            }
        }
        //看是否过期
        if (!(useEndTime == null)) {
            //非永久可领取
            String date = DateUtil.nowDateTimeStr();
            int result = DateUtil.compareDate(date, DateUtil.dateToStr(storeCoupon.getReceiveEndTime(), Constants.DATE_FORMAT), Constants.DATE_FORMAT);
            if (result == 1) {
                //过期了
                throw new TransitException("所使用优惠券已超过使用期限！");
            }
        }

    }

    @Override
    public IPage<ZyOrderDTO> listPage(ZyOrderQuery query, BasePage basePage) {
        IPage<ZyOrder> page = new Page(basePage.getPage(), basePage.getLimit());
        LambdaQueryWrapper<ZyOrder> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(query.getOrderNo())) {
            queryWrapper.eq(ZyOrder::getOrderNo, query.getOrderNo());
        }
        IPage<ZyOrder> zyOrderIPage = zyOrderDao.selectPage(page, queryWrapper);

        return zyOrderIPage.convert(ZyOrderDTO::transform);
    }
}

